#pragma once

#include "Singleton.h"
#include "Thread.h"
#include <unordered_map>
#include <unordered_set>
#include "HttpClient.h"
#include "Macro.h"
#include "MultiBufferQueue.h"

class HttpMgr : public Thread, public Singleton<HttpMgr>
{
public:
    THREAD_RUNTIME(HttpMgr)

    HttpMgr();
    virtual ~HttpMgr();

    HttpClient *AppendTask(
        const std::function<void(HttpClient*, int)> &cbfunc, const char *filepath,
        const char *url, const char *referer = nullptr, const char *cookie = nullptr);

    void AppendTask(const std::function<void(HttpClient*, int)> &cbfunc, HttpClient *client);
    void RemoveTask(HttpClient *client, bool deletable);

    void WakeWorker();

private:
    virtual bool Initialize();
    virtual void Kernel();
    virtual void Abort();
    virtual void Finish();

    void CheckClients();
    void UpdateClients();

    SOCKET pipefd_[2];
    CURLM *multi_handle_;

    std::unordered_set<HttpClient*> client_list_;
    std::unordered_map<HttpClient*, std::function<void(HttpClient*, int)>> observer_list_;
    MultiBufferQueue<std::pair<HttpClient*, std::function<void(HttpClient*, int)>>, 32> waiting_room_;
    MultiBufferQueue<std::pair<HttpClient*, bool>, 32> recycle_bin_;
};

#define sHttpMgr (*HttpMgr::instance())
